﻿using CommonEngine;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

namespace CommonDevelop
{
    /// <summary>
    /// 服务端图片打包下载
    /// </summary>
    public sealed class ImageHelper
    {
        /// <summary>
        /// 公用捕获异常
        /// </summary>
        private static bool CommonException(Func<bool> func)
        {
            try
            {
                return func.Invoke();
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 下载到服务器本地
        /// </summary>
        public static async Task<bool> DownToLocal(string url, string localpath, string filename)
        {
            await Task.CompletedTask;
            return CommonException(() =>
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Timeout = 60000;

                WebResponse response = request.GetResponse();
                using (Stream reader = response.GetResponseStream())
                {
                    FileStream writer = new FileStream(localpath + filename, FileMode.OpenOrCreate, FileAccess.Write);
                    byte[] buff = new byte[1024];
                    int c = 0; //实际读取的字节数
                    while ((c = reader.Read(buff, 0, buff.Length)) > 0)
                    {
                        writer.Write(buff, 0, c);
                    }
                    writer.Close();
                    writer.Dispose();
                    reader.Close();
                    reader.Dispose();
                }
                response.Close();
                response.Dispose();

                return true;
            });
        }

        #region 图片打包下载

        /// <summary>
        /// 下载图片到本地，压缩
        /// </summary>
        /// <param name="urlList">图片列表</param>
        /// <param name="curDirName">要压缩文档的路径</param>
        /// <param name="curFileName">压缩后生成文档保存路径</param>
        /// <returns></returns>
        public static bool ImagePackZip(List<string> urlList, string curDirName, string curFileName)
        {
            return CommonException(() =>
            {
                //1.新建文件夹  
                if (!Directory.Exists(curDirName))
                    Directory.CreateDirectory(curDirName);

                //2.下载文件到服务器临时目录
                foreach (var url in urlList)
                {
                    DownPicToLocal(url, curDirName + "\\");
                    Thread.Sleep(120);   //加个延时，避免上一张图还没下载完就执行下一张图的下载操作
                }

                //3.压缩文件夹
                if (!File.Exists(curFileName))
                    ZipFile.CreateFromDirectory(curDirName, curFileName); //压缩

                //异步删除压缩前，下载的临时文件
                Task.Run(() =>
                {
                    if (Directory.Exists(curDirName))
                        Directory.Delete(curDirName, true);
                });
                return true;
            });
        }

        /// <summary>
        /// 下载一张图片到本地
        /// </summary>
        public static bool DownPicToLocal(string url, string localpath)
        {
            return CommonException(() =>
            {
                string fileprefix = CommonOP.DateRandomGuid();
                var filename = $"{fileprefix}.jpg";

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Timeout = 60000;
                WebResponse response = request.GetResponse();
                using (Stream reader = response.GetResponseStream())
                {
                    FileStream writer = new FileStream(localpath + filename, FileMode.OpenOrCreate, FileAccess.Write);
                    byte[] buff = new byte[1024];
                    int c = 0; //实际读取的字节数
                    while ((c = reader.Read(buff, 0, buff.Length)) > 0)
                    {
                        writer.Write(buff, 0, c);
                    }
                    writer.Close();
                    writer.Dispose();
                    reader.Close();
                    reader.Dispose();
                }
                response.Close();
                response.Dispose();

                return true;
            });
        }

        #endregion

        /// <summary>
        /// 将Base64字符串转换为图片并保存到本地
        /// </summary>
        /// <param name="base64Str">base64字符串</param>
        /// <param name="savePath">图片保存地址，如：/Content/Images/10000.png</param>
        /// <returns></returns>
        public static bool Base64StrToImage(string base64Str, string savePath)
        {
            var ret = true;
            try
            {
                base64Str = base64Str.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "")
                    .Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", ""); //将base64头部信息替换

                var bitmap = Base64StrToImage(base64Str);
                if (bitmap != null)
                {
                    //创建文件夹
                    var folderPath = savePath.Substring(0, savePath.LastIndexOf('\\'));
                    ////FileHelper.CreateDir(folderPath);
                    if (!Directory.Exists(folderPath))
                    {
                        Directory.CreateDirectory(folderPath);
                    }
                    //图片后缀格式
                    var suffix = savePath.Substring(savePath.LastIndexOf('.') + 1,
                        savePath.Length - savePath.LastIndexOf('.') - 1).ToLower();
                    var suffixName = suffix == "png"
                        ? ImageFormat.Png
                        : suffix == "jpg" || suffix == "jpeg"
                            ? ImageFormat.Jpeg
                            : suffix == "bmp"
                                ? ImageFormat.Bmp
                                : suffix == "gif"
                                    ? ImageFormat.Gif
                                    : ImageFormat.Jpeg;

                    //这里复制一份对图像进行保存，否则会出现“GDI+ 中发生一般性错误”的错误提示
                    var bmpNew = new Bitmap(bitmap);
                    bmpNew.Save(savePath, suffixName);
                    bmpNew.Dispose();
                    bitmap.Dispose();
                }
                else
                {
                    ret = false;
                }
            }
            catch
            {
                ret = false;
            }
            return ret;
        }
        private static Bitmap Base64StrToImage(string strbase64)
        {
            try
            {
                byte[] arr = Convert.FromBase64String(strbase64);
                MemoryStream ms = new MemoryStream(arr);
                Bitmap bmp = new Bitmap(ms);
                return bmp;
            }
            catch
            {
                return null;
            }
        }
        /// <summary>
        /// Image 转成 base64
        /// </summary>
        public static string ImageToBase64(string fileFullName)
        {
            try
            {
                Bitmap bmp = new Bitmap(fileFullName);
                MemoryStream ms = new MemoryStream();
                var suffix = fileFullName.Substring(fileFullName.LastIndexOf('.') + 1,
                    fileFullName.Length - fileFullName.LastIndexOf('.') - 1).ToLower();
                var suffixName = suffix == "png"
                    ? ImageFormat.Png
                    : suffix == "jpg" || suffix == "jpeg"
                        ? ImageFormat.Jpeg
                        : suffix == "bmp"
                            ? ImageFormat.Bmp
                            : suffix == "gif"
                                ? ImageFormat.Gif
                                : ImageFormat.Jpeg;

                bmp.Save(ms, suffixName);
                byte[] arr = new byte[ms.Length]; ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length); ms.Close();
                return Convert.ToBase64String(arr);
            }
            catch
            {
                return null;
            }
        }
    }

    /*
     * 设计多图片打包下载逻辑：
     * 1，如果是要拉取腾讯云等资源服务器的图片，
     * 2，我们先把远程图片拉取到本地的临时文件夹，
     * 3，然后压缩临时文件夹，
     * 4，压缩完删除临时文件夹，
     * 5，返回压缩完给用户，
     * 6，用户就去请求下载接口，当下载完后，删除压缩包
     */
}
